abstract class _Math {
  abstract Select(): void
}

abstract class Departments {
  // 系所包含课程对象
  protected mathCourse?: _Math

  // 设置课程
  SetCourse(math: _Math): void {
    this.mathCourse = math
  }

  // 选择课程
  abstract Select(): void
}

class AdvanceMath extends _Math {
  Select(): void {
    console.log('选择了高等数学')
  }
}

class MathAnalysis extends _Math {
  Select(): void {
    console.log('选择数学分析')
  }
}

// 计算机系
class Computer extends Departments {
  Select(): void {
    console.log('计算机系开始选课')
    this.mathCourse?.Select()
  }
}

class Mathematics extends Departments {
  Select(): void {
    console.log('数学系同学开始选课')
    this.mathCourse?.Select()
  }
}

// 客户端代码
(function () {
  let dep: Departments

  dep = new Computer()
  dep.SetCourse(new AdvanceMath())
  dep.Select()

  dep = new Mathematics()
  dep.SetCourse(new MathAnalysis())
  dep.Select()
}())